<?php

if (!class_exists('PHPMailer')) {
    require dirname(__FILE__) . '/PHPMailer_v5.1/class.phpmailer.php';
}

/**
 * 邮件类，必须 Email::getInstance来获取实例
 * @author lovebing <lovebing365@126.com>
 */
class Email extends PHPMailer {

    const  CODE_EMPTY_TO = 10001;
    
    private static $instances = null;

    /**
     * 
     * @param string $host
     * @param int $port
     * @param string $user
     * @param string $pwd
     */
    public function __construct($host, $port, $user, $pwd) {
        parent::__construct(true);

        $this->IsSMTP();

        $this->SMTPAuth = true;
        $this->Port = $port;
        $this->Host = $host;
        $this->Username = $user;
        $this->Password = $pwd;

        $this->From = $user;
    }

    /**
     * 收信人
     * @param array $to
     * @throws Exception
     */
    public function to(array $to) {
        $to = self::filterAddress($to);
        if(empty($to)) {
            throw new Exception('empty address', self::CODE_EMPTY_TO);
        }
        
        foreach ($to as $v) {
            $this->AddAddress($v);
        }
    }

    /**
     * 抄送
     * @param array $cc
     */
    public function cc(array $cc) {        
        $cc = self::filterAddress($cc);
        foreach ($cc as $v) {
            $this->AddCC($v);
        }
    }

    /**
     * 发送
     * @param string $subject
     * @param string $body
     * @return type
     */
    public function sendmail($subject, $body) {
        $this->Subject = $subject;
        $this->MsgHTML($body);
        $this->IsHTML(true);
        return $this->Send();
    }

    /**
     * 获取实例id
     * @param string $host
     * @param int $port
     * @param string $user
     * @param string $pwd
     * @return string
     */
    public static function getInstanceId($host, $port, $user, $pwd) {
        return md5($host . $port . $user . $pwd);
    }

    /**
     * 获取实例
     * @param string $host
     * @param int $port
     * @param string $user
     * @param string $pwd
     * @return Email
     */
    public static function getInstance($host, $port, $user, $pwd) {
        $id = self::getInstanceId($host, $port, $user, $pwd);
        if (!isset(self::$instances[$id]) || !is_a(self::$instances[$id], 'Email')) {
            self::$instances[$id] = new self($host, $port, $user, $pwd);
        }
        $email = self::$instances[$id];
        $email->ready();
        return $email;
    }

    /**
     * 过滤空地址
     * @param array $address
     * @return array
     */
    public static function filterAddress(array $address) {
        $data = array();
        foreach ($address as $addr) {
            if (!empty($addr)) {
                $data[] = $addr;
            }
        }
        return $data;
    }

    /**
     * 准备重新发送
     */
    public function ready() {
        $this->ClearReplyTos();
        $this->ClearAllRecipients();
        $this->ClearAttachments();
        $this->ClearCustomHeaders();
    }

}
